home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Tools / ntail / entryfuncs.c next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  5.3 KB  |  238 lines

  1. /* entryfuncs.c: */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Tools/ntail/RCS/entryfuncs.c,v 6.0 1991/12/18 20:32:10 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Tools/ntail/RCS/entryfuncs.c,v 6.0 1991/12/18 20:32:10 jpo Rel $
  9.  *
  10.  * $Log: entryfuncs.c,v $
  11.  * Revision 6.0  1991/12/18  20:32:10  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15.  
  16.  
  17.  
  18. /*
  19.  * @(#) entryfuncs.c 2.1 89/07/26 19:16:49
  20.  *
  21.  * Package:    ntail version 2
  22.  * File:    entryfuncs.c
  23.  * Description:    procedures to manage individual entries
  24.  *
  25.  * Mon Jul 10 02:56:22 1989 - Chip Rosenthal <chip@vector.Dallas.TX.US>
  26.  *    Original composition.
  27.  */
  28.  
  29.  
  30. #include <stdio.h>
  31. #include <fcntl.h>
  32. #include <sys/types.h>
  33. #include <sys/stat.h>
  34. #include <sys/errno.h>
  35. #include "ntail.h"
  36.  
  37. #ifdef M_XENIX
  38. # undef  NULL
  39. # define NULL 0
  40. #endif
  41.  
  42. extern int errno;
  43.  
  44.  
  45. static struct entry_descrip *E_append(listp,entryp)
  46. struct entry_list *listp;
  47. struct entry_descrip *entryp;
  48. {
  49.     if ( listp->num >= MAX_ENTRIES ) {
  50.     (void) fprintf(stderr,"%s: too many entries (%d max)\n",
  51.         entryp->name, MAX_ENTRIES);
  52.     (void) exit(2);
  53.     }
  54.     listp->list[listp->num++] = entryp;
  55.     Sorted = FALSE;
  56.     return entryp;
  57. }
  58.  
  59.  
  60. static void E_remove(listp,entryno)
  61. struct entry_list *listp;
  62. int entryno;
  63. {
  64.     while ( ++entryno < listp->num )
  65.     listp->list[entryno-1] = listp->list[entryno];
  66.     --listp->num;
  67.     Sorted = FALSE;
  68. }
  69.  
  70.  
  71. static char *list_name(listp)        /* for debug output only */
  72. struct entry_list *listp;
  73. {
  74.     if ( listp == &List_file )    return "<file>";
  75.     if ( listp == &List_dir )    return "<dir>";
  76.     if ( listp == &List_zap )    return "<zap>";
  77.     return "?unknown?";
  78. }
  79.  
  80.  
  81. /*
  82.  * Create a new entry description and append it to a list.
  83.  */
  84. struct entry_descrip *new_entry(listp,name)
  85. struct entry_list *listp;
  86. char *name;
  87. {
  88.     struct entry_descrip *entryp;
  89.     static char malloc_error[] = "malloc: out of space\n";
  90.  
  91.     Dprintf(stderr, ">>> creating entry '%s' on %s list\n",
  92.     name, list_name(listp));
  93.  
  94.     entryp = (struct entry_descrip *) malloc( sizeof(struct entry_descrip) );
  95.     if ( entryp == NULL ) {
  96.     (void) fputs(malloc_error,stderr);
  97.     (void) exit(2);
  98.     }
  99.  
  100.     entryp->name = malloc( (unsigned) strlen(name) + 1 );
  101.     if ( entryp->name == NULL ) {
  102.     (void) fputs(malloc_error,stderr);
  103.     (void) exit(2);
  104.     }
  105.     (void) strcpy(entryp->name,name);
  106.  
  107.     entryp->fd = 0;
  108.     entryp->size =  0;
  109.     entryp->mtime = 0;
  110.  
  111.     return E_append(listp,entryp);
  112. }
  113.  
  114.  
  115. /*
  116.  * Remove an entry from a list and free up its space.
  117.  */
  118. void rmv_entry(listp,entryno)
  119. struct entry_list *listp;
  120. int entryno;
  121. {
  122.     struct entry_descrip *entryp = listp->list[entryno];
  123.     extern void free();
  124.  
  125.     Dprintf(stderr, ">>> removing entry '%s' from %s list\n",
  126.     listp->list[entryno]->name, list_name(listp));
  127.     E_remove(listp,entryno);
  128.     if ( entryp->fd > 0 )
  129.     (void) close(entryp->fd);
  130.     free( entryp->name );
  131.     free( (char *) entryp );
  132. }
  133.  
  134.  
  135. /*
  136.  * Move an entry from one list to another.
  137.  *    In addition we close up the entry if appropriate.
  138.  */
  139. void move_entry(dst_listp,src_listp,src_entryno)
  140. struct entry_list *dst_listp;
  141. struct entry_list *src_listp;
  142. int src_entryno;
  143. {
  144.     struct entry_descrip *entryp = src_listp->list[src_entryno];
  145.  
  146.     Dprintf(stderr, ">>> moving entry '%s' from %s list to %s list\n",
  147.     src_listp->list[src_entryno]->name,
  148.     list_name(src_listp), list_name(dst_listp));
  149.     if ( entryp->fd > 0 ) {
  150.     (void) close(entryp->fd);
  151.     entryp->fd = 0;
  152.     }
  153.     E_remove(src_listp,src_entryno);
  154.     (void) E_append(dst_listp,entryp);
  155.     if ( Reset_status ) {
  156.     entryp->size = 0;
  157.     entryp->mtime = 0;
  158.     }
  159. }
  160.  
  161.  
  162. /*
  163.  * Get the inode status for an entry.
  164.  *    Returns code describing the status of the entry.
  165.  */
  166. int stat_entry(listp,entryno,sbuf)
  167. struct entry_list *listp;
  168. int entryno;
  169. register struct stat *sbuf;
  170. {
  171.     register int status;
  172.     register struct entry_descrip *entryp = listp->list[entryno];
  173.     static int my_gid = -1;
  174.     static int my_uid = -1;
  175.  
  176.     if ( my_gid < 0 ) {
  177.     my_gid = getegid();
  178.     my_uid = geteuid();
  179.     }
  180.  
  181.     status = 
  182.     ( entryp->fd > 0 ? fstat(entryp->fd,sbuf) : stat(entryp->name,sbuf) );
  183.  
  184.     if ( status != 0 )
  185.     return ( errno == ENOENT ? ENTRY_ZAP : ENTRY_ERROR );
  186.  
  187.     if (
  188.     ( ( sbuf->st_mode & 0004 ) == 0 ) &&
  189.     ( ( sbuf->st_mode & 0040 ) == 0 || sbuf->st_gid != my_gid ) &&
  190.     ( ( sbuf->st_mode & 0400 ) == 0 || sbuf->st_uid != my_uid )
  191.     ) {
  192.     errno = EACCES;
  193.     return ENTRY_ERROR;
  194.     }
  195.  
  196.     switch ( sbuf->st_mode & S_IFMT ) {
  197.     case S_IFREG:    return ENTRY_FILE;
  198.     case S_IFDIR:    return ENTRY_DIR;
  199.     default:    return ENTRY_SPECIAL;
  200.     }
  201.  
  202.     /*NOTREACHED*/
  203. }
  204.  
  205.  
  206. /*
  207.  * Open an entry.
  208.  *    Returns 0 if the open is successful, else returns errno.  In the case
  209.  *    of an error, an appropriate diagnostic will be printed, and the entry
  210.  *    will be moved or deleted as required.  If the entry is already opened,
  211.  *    then no action will occur and 0 will be returned.
  212.  */
  213. int open_entry(listp,entryno)
  214. struct entry_list *listp;
  215. int entryno;
  216. {
  217.     struct entry_descrip *entryp = listp->list[entryno];
  218.  
  219.     if ( entryp->fd > 0 )
  220.     return 0;
  221.  
  222.     Dprintf(stderr, ">>> opening entry '%s' on %s list\n",
  223.     listp->list[entryno]->name, list_name(listp));
  224.     if ( (entryp->fd=open(entryp->name,O_RDONLY)) > 0 )
  225.     return 0;
  226.  
  227.     if ( errno == ENOENT ) {
  228.     message( MSSG_ZAPPED, entryp );
  229.     move_entry( &List_zap, listp, entryno );
  230.     } else {
  231.     message( MSSG_OPEN, entryp );
  232.     rmv_entry( listp, entryno );
  233.     }
  234.     return -1;
  235. }
  236.  
  237.  
  238.